<!DOCTYPE html>
<!-- saved from url=(0048)./pdfjs/web/viewer.html -->
<html dir="ltr" mozdisallowselectionprint="" style="--viewer-container-height: 974px;"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta name="google" content="notranslate">
    <title>compressed.tracemonkey-pldi-09.pdf</title>

<!-- This snippet is used in production (included from viewer.html) -->
<link rel="resource" type="application/l10n" href="./pdfjs/web/locale/locale.properties">
<script src="./pdfjs/build/pdf.js"></script>

    <link rel="stylesheet" href="./pdfjs/web/viewer.css">

  <script src="./pdfjs/web/viewer.js"></script>
  
<style>
#clip_copy,#web-copy-btn-wk{
   background:#54aae9 !important
}
.header-btn {
  text-align: right;
}
.header-btn-doc {
  text-align: left;
}
.btn {
  display: inline-block;
  padding: 10px 20px;
  background: #008cba;
  color: #fff;
  text-decoration: none;
  border-radius: 4px;
}
</style>
<style type="text/css">.new-prompt[data-v-be061d42]{position:fixed;z-index:99999;background:rgba(0,0,0,.6);top:0;left:0;right:0;bottom:0;cursor:auto}.new-prompt dialog[data-v-be061d42]{width:380px;position:absolute;left:50%;transform:translate(-50%,-50%);top:50%;border:none;border-radius:5px;padding:10px 20px;margin:0}.new-prompt p[data-v-be061d42]{margin:20px 0 5px}.new-prompt input[data-v-be061d42]{height:25px}.new-prompt input[data-v-be061d42],.new-prompt textarea[data-v-be061d42]{width:100%;border:1px solid #d9d9d9;border-radius:5px}.new-prompt dialog svg[data-v-be061d42]{float:right;cursor:pointer}.new-prompt button[data-v-be061d42]{border-radius:5px;width:60px;height:28px;margin:20px 10px;cursor:pointer}.cancel-btn[data-v-be061d42]{background:#fff;border:1px solid #d9d9d9}.sure-btn[data-v-be061d42]{border:none;background:#7f85ef;color:#fff}.btn-div[data-v-be061d42]{text-align:right}.pro-title[data-v-be061d42]{font-size:16px;font-weight:600;text-align:center}.input-text[data-v-be061d42]{padding:0 0 0 5px}.textarea-text[data-v-be061d42]{padding:5px 0 0 5px}</style><style type="text/css">.message-box[data-v-3436135a]{position:fixed;top:20px;left:50%;transform:translateX(-50%);z-index:99999;width:80%;padding:10px 20px;border-radius:4px;background-color:#f0f0f0;box-shadow:0 2px 4px rgba(0,0,0,.2)}.message-text[data-v-3436135a]{margin-right:8px}.message-info[data-v-3436135a]{color:#35495e}.message-success[data-v-3436135a]{color:#67c23a;background-color:#f2f9ec}.message-warning[data-v-3436135a]{color:#e6a23c}.message-error[data-v-3436135a]{color:#f56c6c}.el-icon-close[data-v-3436135a]{cursor:pointer;margin-left:8px}</style><style>#ai_assistant .popver[refresh]::after {
      content: "刷新";
  }#ai_assistant .popver[copy]::after {
      content: "复制";
  }#ai_assistant .popver[expandSidebar]::after {
      content: "展开侧边栏";
  }</style></head>

  <body tabindex="1">
    <div id="outerContainer">

      <div id="sidebarContainer">
        <div id="toolbarSidebar">
          <div id="toolbarSidebarLeft">
            <div id="sidebarViewButtons" class="splitToolbarButton toggled" role="radiogroup">
              <button id="viewThumbnail" class="toolbarButton toggled" title="显示缩略图" tabindex="2" data-l10n-id="thumbs" role="radio" aria-checked="true" aria-controls="thumbnailView">
                 <span data-l10n-id="thumbs_label">缩略图</span>
              </button>
              <button id="viewOutline" class="toolbarButton" title="显示文档大纲（双击展开/折叠所有项）" tabindex="3" data-l10n-id="document_outline" role="radio" aria-checked="false" aria-controls="outlineView" disabled="">
                 <span data-l10n-id="document_outline_label">文档大纲</span>
              </button>
              <button id="viewAttachments" class="toolbarButton" title="显示附件" tabindex="4" data-l10n-id="attachments" role="radio" aria-checked="false" aria-controls="attachmentsView" disabled="">
                 <span data-l10n-id="attachments_label">附件</span>
              </button>
              <button id="viewLayers" class="toolbarButton" title="显示图层（双击即可将所有图层重置为默认状态）" tabindex="5" data-l10n-id="layers" role="radio" aria-checked="false" aria-controls="layersView" disabled="">
                 <span data-l10n-id="layers_label">图层</span>
              </button>
            </div>
          </div>

          <div id="toolbarSidebarRight">
            <div id="outlineOptionsContainer" class="hidden">
              <div class="verticalToolbarSeparator"></div>

              <button id="currentOutlineItem" class="toolbarButton" disabled="" title="查找当前大纲项目" tabindex="6" data-l10n-id="current_outline_item">
                <span data-l10n-id="current_outline_item_label">当前大纲项目</span>
              </button>
            </div>
          </div>
        </div>
        <div id="sidebarContent">
          <div id="thumbnailView"><a href="./pdfjs/web/viewer.html#page=1" title="第 1 页"><div class="thumbnail selected" data-page-number="1" style="--thumbnail-width: 98px; --thumbnail-height: 126px;"><div class="thumbnailImage"></div></div></a><a href="./pdfjs/web/viewer.html#page=2" title="第 2 页"><div class="thumbnail" data-page-number="2" style="--thumbnail-width: 98px; --thumbnail-height: 126px;"><div class="thumbnailImage"></div></div></a><a href="./pdfjs/web/viewer.html#page=3" title="第 3 页"><div class="thumbnail" data-page-number="3" style="--thumbnail-width: 98px; --thumbnail-height: 126px;"><div class="thumbnailImage"></div></div></a><a href="./pdfjs/web/viewer.html#page=4" title="第 4 页"><div class="thumbnail" data-page-number="4" style="--thumbnail-width: 98px; --thumbnail-height: 126px;"><div class="thumbnailImage"></div></div></a><a href="./pdfjs/web/viewer.html#page=5" title="第 5 页"><div class="thumbnail" data-page-number="5" style="--thumbnail-width: 98px; --thumbnail-height: 126px;"><div class="thumbnailImage"></div></div></a><a href="./pdfjs/web/viewer.html#page=6" title="第 6 页"><div class="thumbnail" data-page-number="6" style="--thumbnail-width: 98px; --thumbnail-height: 126px;"><div class="thumbnailImage"></div></div></a><a href="./pdfjs/web/viewer.html#page=7" title="第 7 页"><div class="thumbnail" data-page-number="7" style="--thumbnail-width: 98px; --thumbnail-height: 126px;"><div class="thumbnailImage"></div></div></a><a href="./pdfjs/web/viewer.html#page=8" title="第 8 页"><div class="thumbnail" data-page-number="8" style="--thumbnail-width: 98px; --thumbnail-height: 126px;"><div class="thumbnailImage"></div></div></a><a href="./pdfjs/web/viewer.html#page=9" title="第 9 页"><div class="thumbnail" data-page-number="9" style="--thumbnail-width: 98px; --thumbnail-height: 126px;"><div class="thumbnailImage"></div></div></a><a href="./pdfjs/web/viewer.html#page=10" title="第 10 页"><div class="thumbnail" data-page-number="10" style="--thumbnail-width: 98px; --thumbnail-height: 126px;"><div class="thumbnailImage"></div></div></a><a href="./pdfjs/web/viewer.html#page=11" title="第 11 页"><div class="thumbnail" data-page-number="11" style="--thumbnail-width: 98px; --thumbnail-height: 126px;"><div class="thumbnailImage"></div></div></a><a href="./pdfjs/web/viewer.html#page=12" title="第 12 页"><div class="thumbnail" data-page-number="12" style="--thumbnail-width: 98px; --thumbnail-height: 126px;"><div class="thumbnailImage"></div></div></a><a href="./pdfjs/web/viewer.html#page=13" title="第 13 页"><div class="thumbnail" data-page-number="13" style="--thumbnail-width: 98px; --thumbnail-height: 126px;"><div class="thumbnailImage"></div></div></a><a href="./pdfjs/web/viewer.html#page=14" title="第 14 页"><div class="thumbnail" data-page-number="14" style="--thumbnail-width: 98px; --thumbnail-height: 126px;"><div class="thumbnailImage"></div></div></a></div>
          <div id="outlineView" class="hidden"></div>
          <div id="attachmentsView" class="hidden"></div>
          <div id="layersView" class="hidden"></div>
        </div>
        <div id="sidebarResizer"></div>
      </div>  <!-- sidebarContainer -->

      <div id="mainContainer">
        <div class="findbar hidden doorHanger" id="findbar">
          <div id="findbarInputContainer">
            <input id="findInput" class="toolbarField" title="查找" placeholder="在文档中查找…" tabindex="91" data-l10n-id="find_input" aria-invalid="false">
            <div class="splitToolbarButton">
              <button id="findPrevious" class="toolbarButton" title="查找词语上一次出现的位置" tabindex="92" data-l10n-id="find_previous">
                <span data-l10n-id="find_previous_label">上一页</span>
              </button>
              <div class="splitToolbarButtonSeparator"></div>
              <button id="findNext" class="toolbarButton" title="查找词语后一次出现的位置" tabindex="93" data-l10n-id="find_next">
                <span data-l10n-id="find_next_label">下一页</span>
              </button>
            </div>
          </div>

          <div id="findbarOptionsOneContainer">
            <input type="checkbox" id="findHighlightAll" class="toolbarField" tabindex="94">
            <label for="findHighlightAll" class="toolbarLabel" data-l10n-id="find_highlight">全部高亮显示</label>
            <input type="checkbox" id="findMatchCase" class="toolbarField" tabindex="95">
            <label for="findMatchCase" class="toolbarLabel" data-l10n-id="find_match_case_label">区分大小写</label>
          </div>
          <div id="findbarOptionsTwoContainer">
            <input type="checkbox" id="findMatchDiacritics" class="toolbarField" tabindex="96">
            <label for="findMatchDiacritics" class="toolbarLabel" data-l10n-id="find_match_diacritics_label">匹配变音符号</label>
            <input type="checkbox" id="findEntireWord" class="toolbarField" tabindex="97">
            <label for="findEntireWord" class="toolbarLabel" data-l10n-id="find_entire_word_label">全词匹配</label>
          </div>

          <div id="findbarMessageContainer" aria-live="polite">
            <span id="findResultsCount" class="toolbarLabel"></span>
            <span id="findMsg" class="toolbarLabel"></span>
          </div>
        </div>  <!-- findbar -->

        <div class="editorParamsToolbar hidden doorHangerRight" id="editorFreeTextParamsToolbar">
          <div class="editorParamsToolbarContainer">
            <div class="editorParamsSetter">
              <label for="editorFreeTextColor" class="editorParamsLabel" data-l10n-id="editor_free_text_color">颜色</label>
              <input type="color" id="editorFreeTextColor" class="editorParamsColor" tabindex="100">
            </div>
            <div class="editorParamsSetter">
              <label for="editorFreeTextFontSize" class="editorParamsLabel" data-l10n-id="editor_free_text_size">字号</label>
              <input type="range" id="editorFreeTextFontSize" class="editorParamsSlider" value="10" min="5" max="100" step="1" tabindex="101">
            </div>
          </div>
        </div>

        <div class="editorParamsToolbar hidden doorHangerRight" id="editorInkParamsToolbar">
          <div class="editorParamsToolbarContainer">
            <div class="editorParamsSetter">
              <label for="editorInkColor" class="editorParamsLabel" data-l10n-id="editor_ink_color">颜色</label>
              <input type="color" id="editorInkColor" class="editorParamsColor" tabindex="102">
            </div>
            <div class="editorParamsSetter">
              <label for="editorInkThickness" class="editorParamsLabel" data-l10n-id="editor_ink_thickness">粗细</label>
              <input type="range" id="editorInkThickness" class="editorParamsSlider" value="1" min="1" max="20" step="1" tabindex="103">
            </div>
            <div class="editorParamsSetter">
              <label for="editorInkOpacity" class="editorParamsLabel" data-l10n-id="editor_ink_opacity">不透明度</label>
              <input type="range" id="editorInkOpacity" class="editorParamsSlider" value="100" min="1" max="100" step="1" tabindex="104">
            </div>
          </div>
        </div>

        <div class="editorParamsToolbar hidden doorHangerRight" id="editorStampParamsToolbar">
          <div class="editorParamsToolbarContainer">
            <button id="editorStampAddImage" class="secondaryToolbarButton" title="添加图像" tabindex="105" data-l10n-id="editor_stamp_add_image">
              <span data-l10n-id="editor_stamp_add_image_label">添加图像</span>
            </button>
          </div>
        </div>

        <div id="secondaryToolbar" class="secondaryToolbar hidden doorHangerRight">
          <div id="secondaryToolbarButtonContainer">
            <button id="secondaryOpenFile" class="secondaryToolbarButton visibleLargeView" title="打开文件" tabindex="51" data-l10n-id="open_file">
              <span data-l10n-id="open_file_label">打开</span>
            </button>

            <button id="secondaryPrint" class="secondaryToolbarButton visibleMediumView" title="打印" tabindex="52" data-l10n-id="print">
              <span data-l10n-id="print_label">打印</span>
            </button>

            <button id="secondaryDownload" class="secondaryToolbarButton visibleMediumView" title="保存" tabindex="53" data-l10n-id="save">
              <span data-l10n-id="save_label">保存</span>
            </button>

            <div class="horizontalToolbarSeparator visibleLargeView"></div>

            <button id="presentationMode" class="secondaryToolbarButton" title="切换到演示模式" tabindex="54" data-l10n-id="presentation_mode">
              <span data-l10n-id="presentation_mode_label">演示模式</span>
            </button>

            <a href="./pdfjs/web/viewer.html#page=1&amp;zoom=auto,-249,798" id="viewBookmark" class="secondaryToolbarButton" title="当前页面（在当前页面查看 URL）" tabindex="55" data-l10n-id="bookmark1">
              <span data-l10n-id="bookmark1_label">当前页面</span>
            </a>

            <div id="viewBookmarkSeparator" class="horizontalToolbarSeparator"></div>

            <button id="firstPage" class="secondaryToolbarButton" title="转到第一页" tabindex="56" data-l10n-id="first_page" disabled="">
              <span data-l10n-id="first_page_label">转到第一页</span>
            </button>
            <button id="lastPage" class="secondaryToolbarButton" title="转到最后一页" tabindex="57" data-l10n-id="last_page">
              <span data-l10n-id="last_page_label">转到最后一页</span>
            </button>

            <div class="horizontalToolbarSeparator"></div>

            <button id="pageRotateCw" class="secondaryToolbarButton" title="顺时针旋转" tabindex="58" data-l10n-id="page_rotate_cw">
              <span data-l10n-id="page_rotate_cw_label">顺时针旋转</span>
            </button>
            <button id="pageRotateCcw" class="secondaryToolbarButton" title="逆时针旋转" tabindex="59" data-l10n-id="page_rotate_ccw">
              <span data-l10n-id="page_rotate_ccw_label">逆时针旋转</span>
            </button>

            <div class="horizontalToolbarSeparator"></div>

            <div id="cursorToolButtons" role="radiogroup">
              <button id="cursorSelectTool" class="secondaryToolbarButton toggled" title="启用文本选择工具" tabindex="60" data-l10n-id="cursor_text_select_tool" role="radio" aria-checked="true">
                <span data-l10n-id="cursor_text_select_tool_label">文本选择工具</span>
              </button>
              <button id="cursorHandTool" class="secondaryToolbarButton" title="启用手形工具" tabindex="61" data-l10n-id="cursor_hand_tool" role="radio" aria-checked="false">
                <span data-l10n-id="cursor_hand_tool_label">手形工具</span>
              </button>
            </div>

            <div class="horizontalToolbarSeparator"></div>

            <div id="scrollModeButtons" role="radiogroup">
              <button id="scrollPage" class="secondaryToolbarButton" title="使用页面滚动" tabindex="62" data-l10n-id="scroll_page" role="radio" aria-checked="false">
                <span data-l10n-id="scroll_page_label">页面滚动</span>
              </button>
              <button id="scrollVertical" class="secondaryToolbarButton toggled" title="使用垂直滚动" tabindex="63" data-l10n-id="scroll_vertical" role="radio" aria-checked="true">
                <span data-l10n-id="scroll_vertical_label">垂直滚动</span>
              </button>
              <button id="scrollHorizontal" class="secondaryToolbarButton" title="使用水平滚动" tabindex="64" data-l10n-id="scroll_horizontal" role="radio" aria-checked="false">
                <span data-l10n-id="scroll_horizontal_label">水平滚动</span>
              </button>
              <button id="scrollWrapped" class="secondaryToolbarButton" title="使用平铺滚动" tabindex="65" data-l10n-id="scroll_wrapped" role="radio" aria-checked="false">
                <span data-l10n-id="scroll_wrapped_label">平铺滚动</span>
              </button>
            </div>

            <div class="horizontalToolbarSeparator"></div>

            <div id="spreadModeButtons" role="radiogroup">
              <button id="spreadNone" class="secondaryToolbarButton toggled" title="不加入衔接页" tabindex="66" data-l10n-id="spread_none" role="radio" aria-checked="true">
                <span data-l10n-id="spread_none_label">单页视图</span>
              </button>
              <button id="spreadOdd" class="secondaryToolbarButton" title="加入衔接页使奇数页作为起始页" tabindex="67" data-l10n-id="spread_odd" role="radio" aria-checked="false">
                <span data-l10n-id="spread_odd_label">双页视图</span>
              </button>
              <button id="spreadEven" class="secondaryToolbarButton" title="加入衔接页使偶数页作为起始页" tabindex="68" data-l10n-id="spread_even" role="radio" aria-checked="false">
                <span data-l10n-id="spread_even_label">书籍视图</span>
              </button>
            </div>

            <div class="horizontalToolbarSeparator"></div>

            <button id="documentProperties" class="secondaryToolbarButton" title="文档属性…" tabindex="69" data-l10n-id="document_properties" aria-controls="documentPropertiesDialog">
              <span data-l10n-id="document_properties_label">文档属性…</span>
            </button>
          </div>
        </div>  <!-- secondaryToolbar -->

        <div class="toolbar">
          <div id="toolbarContainer">
            <div id="toolbarViewer">
              <div id="toolbarViewerLeft">
                <button id="sidebarToggle" class="toolbarButton" title="切换侧栏" tabindex="11" data-l10n-id="toggle_sidebar" aria-expanded="false" aria-controls="sidebarContainer">
                  <span data-l10n-id="toggle_sidebar_label">切换侧栏</span>
                </button>
                <div class="toolbarButtonSpacer"></div>
                <button id="viewFind" class="toolbarButton" title="在文档中查找" tabindex="12" data-l10n-id="findbar" aria-expanded="false" aria-controls="findbar">
                  <span data-l10n-id="findbar_label">查找</span>
                </button>
                <div class="splitToolbarButton hiddenSmallView">
                  <button class="toolbarButton" title="上一页" id="previous" tabindex="13" data-l10n-id="previous" disabled="">
                    <span data-l10n-id="previous_label">上一页</span>
                  </button>
                  <div class="splitToolbarButtonSeparator"></div>
                  <button class="toolbarButton" title="下一页" id="next" tabindex="14" data-l10n-id="next">
                    <span data-l10n-id="next_label">下一页</span>
                  </button>
                </div>
                <input type="number" id="pageNumber" class="toolbarField" title="页面" value="1" min="1" tabindex="15" data-l10n-id="page" autocomplete="off" max="14">
                <span id="numPages" class="toolbarLabel">/ 14</span>
              </div>
              <div id="toolbarViewerRight">
                <button id="openFile" class="toolbarButton hiddenLargeView" title="打开文件" tabindex="31" data-l10n-id="open_file">
                  <span data-l10n-id="open_file_label">打开</span>
                </button>

                <button id="print" class="toolbarButton hiddenMediumView" title="打印" tabindex="32" data-l10n-id="print">
                  <span data-l10n-id="print_label">打印</span>
                </button>

                <button id="download" class="toolbarButton hiddenMediumView" title="保存" tabindex="33" data-l10n-id="save">
                  <span data-l10n-id="save_label">保存</span>
                </button>

                <div class="verticalToolbarSeparator hiddenMediumView"></div>

                <div id="editorModeButtons" class="splitToolbarButton toggled" role="radiogroup">
                  <button id="editorFreeText" class="toolbarButton" title="文本" role="radio" aria-checked="false" aria-controls="editorFreeTextParamsToolbar" tabindex="34" data-l10n-id="editor_free_text2">
                    <span data-l10n-id="editor_free_text2_label">文本</span>
                  </button>
                  <button id="editorInk" class="toolbarButton" title="绘图" role="radio" aria-checked="false" aria-controls="editorInkParamsToolbar" tabindex="35" data-l10n-id="editor_ink2">
                    <span data-l10n-id="editor_ink2_label">绘图</span>
                  </button>
                  <button id="editorStamp" class="toolbarButton" title="添加或编辑图像" role="radio" aria-checked="false" aria-controls="editorStampParamsToolbar" tabindex="36" data-l10n-id="editor_stamp1">
                    <span data-l10n-id="editor_stamp1_label">添加或编辑图像</span>
                  </button>
                </div>

                <div id="editorModeSeparator" class="verticalToolbarSeparator"></div>

                <button id="secondaryToolbarToggle" class="toolbarButton" title="工具" tabindex="48" data-l10n-id="tools" aria-expanded="false" aria-controls="secondaryToolbar">
                  <span data-l10n-id="tools_label">工具</span>
                </button>
              </div>
              <div id="toolbarViewerMiddle">
                <div class="splitToolbarButton">
                  <button id="zoomOut" class="toolbarButton" title="缩小" tabindex="21" data-l10n-id="zoom_out">
                    <span data-l10n-id="zoom_out_label">缩小</span>
                  </button>
                  <div class="splitToolbarButtonSeparator"></div>
                  <button id="zoomIn" class="toolbarButton" title="放大" tabindex="22" data-l10n-id="zoom_in">
                    <span data-l10n-id="zoom_in_label">放大</span>
                   </button>
                </div>
                <span id="scaleSelectContainer" class="dropdownToolbarButton">
                  <select id="scaleSelect" title="缩放" tabindex="23" data-l10n-id="zoom">
                    <option id="pageAutoOption" title="" value="auto" selected="selected" data-l10n-id="page_scale_auto">自动缩放</option>
                    <option id="pageActualOption" title="" value="page-actual" data-l10n-id="page_scale_actual">实际大小</option>
                    <option id="pageFitOption" title="" value="page-fit" data-l10n-id="page_scale_fit">适合页面</option>
                    <option id="pageWidthOption" title="" value="page-width" data-l10n-id="page_scale_width">适合页宽</option>
                    <option id="customScaleOption" title="" value="custom" disabled="disabled" hidden="true"></option>
                    <option title="" value="0.5" data-l10n-id="page_scale_percent" data-l10n-args="{ &quot;scale&quot;: 50 }">50%</option>
                    <option title="" value="0.75" data-l10n-id="page_scale_percent" data-l10n-args="{ &quot;scale&quot;: 75 }">75%</option>
                    <option title="" value="1" data-l10n-id="page_scale_percent" data-l10n-args="{ &quot;scale&quot;: 100 }">100%</option>
                    <option title="" value="1.25" data-l10n-id="page_scale_percent" data-l10n-args="{ &quot;scale&quot;: 125 }">125%</option>
                    <option title="" value="1.5" data-l10n-id="page_scale_percent" data-l10n-args="{ &quot;scale&quot;: 150 }">150%</option>
                    <option title="" value="2" data-l10n-id="page_scale_percent" data-l10n-args="{ &quot;scale&quot;: 200 }">200%</option>
                    <option title="" value="3" data-l10n-id="page_scale_percent" data-l10n-args="{ &quot;scale&quot;: 300 }">300%</option>
                    <option title="" value="4" data-l10n-id="page_scale_percent" data-l10n-args="{ &quot;scale&quot;: 400 }">400%</option>
                  </select>
                </span>
              </div>
            </div>
            <div id="loadingBar" class="hidden" style="--progressBar-percent: 100%; --progressBar-end-offset: 15px;">
              <div class="progress">
                <div class="glimmer">
                </div>
              </div>
            </div>
          </div>
        </div>

        <div id="viewerContainer" tabindex="0">
          <div id="hiddenCopyElement"></div><div id="viewer" class="pdfViewer" style="--scale-factor: 1.6666666666666665;"><div class="page" data-page-number="1" role="region" aria-label="第 1 页" data-loaded="true" style="width: calc(var(--scale-factor) * 612px); height: calc(var(--scale-factor) * 792px);"><div class="canvasWrapper"><canvas role="presentation" width="1020" height="1320" style="width: 1020px; height: 1320px;"></canvas></div><div class="textLayer" data-main-rotation="0" style="width: calc(var(--scale-factor) * 612px); height: calc(var(--scale-factor) * 792px);"><span role="presentation" dir="ltr" style="left: 13.16%; top: 9.68%; font-size: calc(var(--scale-factor)*17.93px); font-family: sans-serif; transform: scaleX(0.970171);">Trace-based Just-in-Time Type Specialization for Dynamic</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 43.09%; top: 12.19%; font-size: calc(var(--scale-factor)*17.93px); font-family: sans-serif; transform: scaleX(0.93227);">Languages</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 19.66%; top: 17.44%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif; transform: scaleX(0.90492);">Andreas Gal</span><span role="presentation" dir="ltr" style="left: 28.66%; top: 17.27%; font-size: calc(var(--scale-factor)*7.97px); font-family: monospace;">∗</span><span role="presentation" dir="ltr" style="left: 29.43%; top: 17.25%; font-size: calc(var(--scale-factor)*7.97px); font-family: sans-serif;">+</span><span role="presentation" dir="ltr" style="left: 30.59%; top: 17.44%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif; transform: scaleX(0.911013);">, Brendan Eich</span><span role="presentation" dir="ltr" style="left: 41.28%; top: 17.27%; font-size: calc(var(--scale-factor)*7.97px); font-family: monospace;">∗</span><span role="presentation" dir="ltr" style="left: 42.06%; top: 17.44%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif; transform: scaleX(0.915637);">, Mike Shaver</span><span role="presentation" dir="ltr" style="left: 52.07%; top: 17.27%; font-size: calc(var(--scale-factor)*7.97px); font-family: monospace;">∗</span><span role="presentation" dir="ltr" style="left: 52.84%; top: 17.44%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif; transform: scaleX(0.921371);">, David Anderson</span><span role="presentation" dir="ltr" style="left: 65.49%; top: 17.27%; font-size: calc(var(--scale-factor)*7.97px); font-family: monospace;">∗</span><span role="presentation" dir="ltr" style="left: 66.26%; top: 17.44%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif; transform: scaleX(0.941524);">, David Mandelin</span><span role="presentation" dir="ltr" style="left: 78.81%; top: 17.27%; font-size: calc(var(--scale-factor)*7.97px); font-family: monospace;">∗</span><span role="presentation" dir="ltr" style="left: 79.58%; top: 17.44%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif;">,</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 15.28%; top: 19.08%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif; transform: scaleX(0.914866);">Mohammad R. Haghighat</span><span role="presentation" dir="ltr" style="left: 33.94%; top: 18.89%; font-size: calc(var(--scale-factor)*7.97px); font-family: sans-serif;">$</span><span role="presentation" dir="ltr" style="left: 34.71%; top: 19.08%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif; transform: scaleX(0.925119);">, Blake Kaplan</span><span role="presentation" dir="ltr" style="left: 45.38%; top: 18.91%; font-size: calc(var(--scale-factor)*7.97px); font-family: monospace;">∗</span><span role="presentation" dir="ltr" style="left: 46.16%; top: 19.08%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif; transform: scaleX(0.905968);">, Graydon Hoare</span><span role="presentation" dir="ltr" style="left: 58.14%; top: 18.91%; font-size: calc(var(--scale-factor)*7.97px); font-family: monospace;">∗</span><span role="presentation" dir="ltr" style="left: 58.91%; top: 19.08%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif; transform: scaleX(0.927422);">, Boris Zbarsky</span><span role="presentation" dir="ltr" style="left: 69.98%; top: 18.91%; font-size: calc(var(--scale-factor)*7.97px); font-family: monospace;">∗</span><span role="presentation" dir="ltr" style="left: 70.75%; top: 19.08%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif; transform: scaleX(0.901745);">, Jason Orendorff</span><span role="presentation" dir="ltr" style="left: 83.19%; top: 18.91%; font-size: calc(var(--scale-factor)*7.97px); font-family: monospace;">∗</span><span role="presentation" dir="ltr" style="left: 83.96%; top: 19.08%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif;">,</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 11.16%; top: 20.71%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif; transform: scaleX(0.856752);">Jesse Ruderman</span><span role="presentation" dir="ltr" style="left: 22.74%; top: 20.54%; font-size: calc(var(--scale-factor)*7.97px); font-family: monospace;">∗</span><span role="presentation" dir="ltr" style="left: 23.52%; top: 20.71%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif; transform: scaleX(0.941503);">, Edwin Smith</span><span role="presentation" dir="ltr" style="left: 33.81%; top: 20.52%; font-size: calc(var(--scale-factor)*7.97px); font-family: sans-serif;">#</span><span role="presentation" dir="ltr" style="left: 35.05%; top: 20.71%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif; transform: scaleX(0.933638);">, Rick Reitmaier</span><span role="presentation" dir="ltr" style="left: 46.84%; top: 20.52%; font-size: calc(var(--scale-factor)*7.97px); font-family: sans-serif;">#</span><span role="presentation" dir="ltr" style="left: 48.07%; top: 20.71%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif; transform: scaleX(0.922343);">, Michael Bebenita</span><span role="presentation" dir="ltr" style="left: 61.65%; top: 20.52%; font-size: calc(var(--scale-factor)*7.97px); font-family: sans-serif;">+</span><span role="presentation" dir="ltr" style="left: 62.81%; top: 20.71%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif; transform: scaleX(0.897697);">, Mason Chang</span><span role="presentation" dir="ltr" style="left: 73.7%; top: 20.52%; font-size: calc(var(--scale-factor)*7.97px); font-family: sans-serif; transform: scaleX(1.55805);">+#</span><span role="presentation" dir="ltr" style="left: 76.09%; top: 20.71%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif; transform: scaleX(0.923001);">, Michael Franz</span><span role="presentation" dir="ltr" style="left: 87.38%; top: 20.52%; font-size: calc(var(--scale-factor)*7.97px); font-family: sans-serif;">+</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 43.49%; top: 22.81%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.951574);">Mozilla Corporation</span><span role="presentation" dir="ltr" style="left: 55.5%; top: 22.65%; font-size: calc(var(--scale-factor)*5.98px); font-family: monospace;">∗</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 14.87%; top: 24.06%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;">{</span><span role="presentation" dir="ltr" style="left: 15.62%; top: 24.09%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace; transform: scaleX(0.872377);">gal,brendan,shaver,danderson,dmandelin,mrbkap,graydon,bz,jorendorff,jruderman</span><span role="presentation" dir="ltr" style="left: 74.84%; top: 24.06%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;">}</span><span role="presentation" dir="ltr" style="left: 75.6%; top: 24.09%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace; transform: scaleX(0.872399);">@mozilla.com</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 43.64%; top: 26.11%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.923503);">Adobe Corporation</span><span role="presentation" dir="ltr" style="left: 54.99%; top: 25.94%; font-size: calc(var(--scale-factor)*5.98px); font-family: sans-serif;">#</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 38.71%; top: 27.37%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;">{</span><span role="presentation" dir="ltr" style="left: 39.46%; top: 27.39%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace; transform: scaleX(0.872399);">edwsmith,rreitmai</span><span role="presentation" dir="ltr" style="left: 52.54%; top: 27.37%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;">}</span><span role="presentation" dir="ltr" style="left: 53.29%; top: 27.39%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace; transform: scaleX(0.872399);">@adobe.com</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 44.44%; top: 29.45%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.935878);">Intel Corporation</span><span role="presentation" dir="ltr" style="left: 54.57%; top: 29.28%; font-size: calc(var(--scale-factor)*5.98px); font-family: sans-serif;">$</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 37.56%; top: 30.71%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;">{</span><span role="presentation" dir="ltr" style="left: 38.31%; top: 30.73%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace; transform: scaleX(0.872399);">mohammad.r.haghighat</span><span role="presentation" dir="ltr" style="left: 53.69%; top: 30.71%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;">}</span><span role="presentation" dir="ltr" style="left: 54.44%; top: 30.73%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace; transform: scaleX(0.872399);">@intel.com</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 40.22%; top: 32.71%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.958401);">University of California, Irvine</span><span role="presentation" dir="ltr" style="left: 58.47%; top: 32.54%; font-size: calc(var(--scale-factor)*5.98px); font-family: sans-serif;">+</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 37.94%; top: 33.97%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;">{</span><span role="presentation" dir="ltr" style="left: 38.69%; top: 33.99%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace; transform: scaleX(0.872399);">mbebenit,changm,franz</span><span role="presentation" dir="ltr" style="left: 54.85%; top: 33.97%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;">}</span><span role="presentation" dir="ltr" style="left: 55.6%; top: 33.99%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace; transform: scaleX(0.872399);">@uci.edu</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 42.32%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif; transform: scaleX(1.01528);">Abstract</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 44.28%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.928456);">Dynamic languages such as JavaScript are more difﬁcult to com-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 45.54%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.919426);">pile than statically typed ones. Since no concrete type information</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 46.8%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.888795);">is available, traditional compilers need to emit generic code that can</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 48.06%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.897659);">handle all possible type combinations at runtime. We present an al-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 49.31%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.939213);">ternative compilation technique for dynamically-typed languages</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 50.57%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.910675);">that identiﬁes frequently executed loop traces at run-time and then</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 51.83%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.944767);">generates machine code on the ﬂy that is specialized for the ac-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 53.09%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.93736);">tual dynamic types occurring on each path through the loop. Our</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 54.35%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.897054);">method provides cheap inter-procedural type specialization, and an</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 55.6%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.928409);">elegant and efﬁcient way of incrementally compiling lazily discov-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 56.86%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.8976);">ered alternative paths through nested loops. We have implemented</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 58.12%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.912455);">a dynamic compiler for JavaScript based on our technique and we</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 59.38%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.921193);">have measured speedups of 10x and more for certain benchmark</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 60.63%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.894987);">programs.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 62.6%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.947521);">Categories and Subject Descriptors</span><span role="presentation" dir="ltr" style="left: 30.65%; top: 62.6%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 32.12%; top: 62.6%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(1.00084);">D.3.4 [</span><span role="presentation" dir="ltr" style="left: 36.43%; top: 62.6%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.944954);">Programming Lan-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 63.86%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.857796);">guages</span><span role="presentation" dir="ltr" style="left: 12.94%; top: 63.86%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.898491);">]: Processors —</span><span role="presentation" dir="ltr" style="left: 22.3%; top: 63.86%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 22.67%; top: 63.86%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.909914);">Incremental compilers, code generation</span><span role="presentation" dir="ltr" style="left: 46%; top: 63.86%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;">.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 65.83%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.942828);">General Terms</span><span role="presentation" dir="ltr" style="left: 17.88%; top: 65.83%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 19.34%; top: 65.83%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.92065);">Design, Experimentation, Measurement, Perfor-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 67.09%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.872518);">mance.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 69.06%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.902314);">Keywords</span><span role="presentation" dir="ltr" style="left: 14.63%; top: 69.06%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 16.09%; top: 69.06%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.911841);">JavaScript, just-in-time compilation, trace trees.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 71.71%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif; transform: scaleX(0.900028);">1.</span><span role="presentation" dir="ltr" style="left: 10.17%; top: 71.71%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 11.96%; top: 71.71%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif; transform: scaleX(1.03939);">Introduction</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 73.67%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.902505);">Dynamic languages</span><span role="presentation" dir="ltr" style="left: 20.43%; top: 73.67%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 20.76%; top: 73.67%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.878036);">such as JavaScript, Python, and Ruby, are pop-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 74.93%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.887193);">ular since they are expressive, accessible to non-experts, and make</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 76.19%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.907303);">deployment as easy as distributing a source ﬁle. They are used for</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 77.45%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.948704);">small scripts as well as for complex applications. JavaScript, for</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 78.7%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.9125);">example, is the de facto standard for client-side web programming</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 84.16%; font-size: calc(var(--scale-factor)*6.97px); font-family: sans-serif; transform: scaleX(0.956034);">Permission to make digital or hard copies of all or part of this work for personal or</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 85.16%; font-size: calc(var(--scale-factor)*6.97px); font-family: sans-serif; transform: scaleX(0.910811);">classroom use is granted without fee provided that copies are not made or distributed</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 86.17%; font-size: calc(var(--scale-factor)*6.97px); font-family: sans-serif; transform: scaleX(0.905462);">for proﬁt or commercial advantage and that copies bear this notice and the full citation</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 87.18%; font-size: calc(var(--scale-factor)*6.97px); font-family: sans-serif; transform: scaleX(0.916251);">on the ﬁrst page. To copy otherwise, to republish, to post on servers or to redistribute</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 88.18%; font-size: calc(var(--scale-factor)*6.97px); font-family: sans-serif; transform: scaleX(0.909851);">to lists, requires prior speciﬁc permission and/or a fee.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 89.44%; font-size: calc(var(--scale-factor)*6.97px); font-family: sans-serif; transform: scaleX(0.993224);">PLDI’09,</span><span role="presentation" dir="ltr" style="left: 13.16%; top: 89.44%; font-size: calc(var(--scale-factor)*6.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 14.32%; top: 89.44%; font-size: calc(var(--scale-factor)*6.97px); font-family: sans-serif; transform: scaleX(0.913028);">June 15–20, 2009, Dublin, Ireland.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 90.45%; font-size: calc(var(--scale-factor)*6.97px); font-family: sans-serif; transform: scaleX(1.00708);">Copyright c</span><span role="presentation" dir="ltr" style="left: 13.72%; top: 90.46%; font-size: calc(var(--scale-factor)*6.97px); font-family: monospace;">©</span><span role="presentation" dir="ltr" style="left: 15.02%; top: 90.46%; font-size: calc(var(--scale-factor)*6.97px); font-family: monospace;"> </span><span role="presentation" dir="ltr" style="left: 15.3%; top: 90.45%; font-size: calc(var(--scale-factor)*6.97px); font-family: sans-serif; transform: scaleX(0.906583);">2009 ACM 978-1-60558-392-1/09/06. . . $5.00</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 42.52%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.921208);">and is used for the application logic of browser-based productivity</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 43.78%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.93931);">applications such as Google Mail, Google Docs and Zimbra Col-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 45.04%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.96958);">laboration Suite. In this domain, in order to provide a ﬂuid user</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 46.29%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.890374);">experience and enable a new generation of applications, virtual ma-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 47.55%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.906684);">chines must provide a low startup time and high performance.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 53.75%; top: 48.81%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.936314);">Compilers for statically typed languages rely on type informa-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 50.07%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.898766);">tion to generate efﬁcient machine code. In a dynamically typed pro-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 51.33%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.924779);">gramming language such as JavaScript, the types of expressions</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 52.58%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.935675);">may vary at runtime. This means that the compiler can no longer</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 53.84%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.923013);">easily transform operations into machine instructions that operate</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 55.1%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.92481);">on one speciﬁc type. Without exact type information, the compiler</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 56.36%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.926582);">must emit slower generalized machine code that can deal with all</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 57.62%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.937521);">potential type combinations. While compile-time static type infer-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 58.87%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.965622);">ence might be able to gather type information to generate opti-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 60.13%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.935659);">mized machine code, traditional static analysis is very expensive</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 61.39%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.91941);">and hence not well suited for the highly interactive environment of</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 62.65%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.892654);">a web browser.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 53.75%; top: 63.91%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.942691);">We present a trace-based compilation technique for dynamic</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 65.16%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.915911);">languages that reconciles speed of compilation with excellent per-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 66.42%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.877476);">formance of the generated machine code. Our system uses a mixed-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 67.68%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.887179);">mode execution approach: the system starts running JavaScript in a</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 68.94%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.909084);">fast-starting bytecode interpreter. As the program runs, the system</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 70.19%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.929517);">identiﬁes</span><span role="presentation" dir="ltr" style="left: 57.17%; top: 70.19%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 57.79%; top: 70.19%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.919734);">hot</span><span role="presentation" dir="ltr" style="left: 59.67%; top: 70.19%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 60.31%; top: 70.19%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.917693);">(frequently executed) bytecode sequences, records</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 71.45%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.943609);">them, and compiles them to fast native code. We call such a se-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 72.71%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.902304);">quence of instructions a</span><span role="presentation" dir="ltr" style="left: 65.76%; top: 72.71%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 66.12%; top: 72.71%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.918018);">trace</span><span role="presentation" dir="ltr" style="left: 69.11%; top: 72.71%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;">.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 53.75%; top: 73.97%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.956008);">Unlike method-based dynamic compilers, our dynamic com-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 75.23%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.963731);">piler operates at the granularity of individual loops. This design</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 76.48%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.941041);">choice is based on the expectation that programs spend most of</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 77.74%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.941073);">their time in hot loops. Even in dynamically typed languages, we</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 79%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.895333);">expect hot loops to be mostly</span><span role="presentation" dir="ltr" style="left: 68.78%; top: 79%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 69.11%; top: 79%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.897438);">type-stable</span><span role="presentation" dir="ltr" style="left: 75.53%; top: 79%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.888453);">, meaning that the types of</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 80.26%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.897143);">values are invariant. (12) For example, we would expect loop coun-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 81.52%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.903955);">ters that start as integers to remain integers for all iterations. When</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 82.77%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.914164);">both of these expectations hold, a trace-based compiler can cover</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 84.03%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.907348);">the program execution with a small number of type-specialized, ef-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 85.29%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.925946);">ﬁciently compiled traces.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 53.75%; top: 86.55%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.910063);">Each compiled trace covers one path through the program with</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 87.81%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.893753);">one mapping of values to types. When the VM executes a compiled</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 89.06%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.991575);">trace, it cannot guarantee that the same path will be followed</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 90.32%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.967657);">or that the same types will occur in subsequent loop iterations.</span><div class="endOfContent" style=""></div></div><div class="annotationLayer" hidden=""></div><div class="annotationEditorLayer" tabindex="0" hidden="" dir="ltr" data-main-rotation="0" style="pointer-events: none; width: calc(var(--scale-factor) * 612px); height: calc(var(--scale-factor) * 792px);"></div></div><div class="page" data-page-number="2" role="region" aria-label="第 2 页" data-loaded="true" style="width: calc(var(--scale-factor) * 612px); height: calc(var(--scale-factor) * 792px);"><div class="canvasWrapper"><canvas role="presentation" width="1020" height="1320" style="width: 1020px; height: 1320px;"></canvas></div><div class="textLayer" data-main-rotation="0" style="width: calc(var(--scale-factor) * 612px); height: calc(var(--scale-factor) * 792px);"><span role="presentation" dir="ltr" style="left: 8.82%; top: 9.17%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.895182);">Hence, recording and compiling a trace</span><span role="presentation" dir="ltr" style="left: 31.63%; top: 9.17%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 31.94%; top: 9.17%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.871788);">speculates</span><span role="presentation" dir="ltr" style="left: 38.04%; top: 9.17%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 38.35%; top: 9.17%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.86831);">that the path and</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 10.43%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.905574);">typing will be exactly as they were during recording for subsequent</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 11.69%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.921909);">iterations of the loop.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 10.78%; top: 12.94%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.922563);">Every compiled trace contains all the</span><span role="presentation" dir="ltr" style="left: 32.78%; top: 12.94%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 33.2%; top: 12.94%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.89684);">guards</span><span role="presentation" dir="ltr" style="left: 37.21%; top: 12.94%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 37.63%; top: 12.94%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.90705);">(checks) required</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 14.2%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.981458);">to validate the speculation. If one of the guards fails (if control</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 15.46%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.965008);">ﬂow is different, or a value of a different type is generated), the</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 16.72%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.960998);">trace exits. If an exit becomes hot, the VM can record a</span><span role="presentation" dir="ltr" style="left: 43.24%; top: 16.72%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 43.79%; top: 16.72%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.917126);">branch</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 17.98%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.918018);">trace</span><span role="presentation" dir="ltr" style="left: 11.81%; top: 17.98%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 12.17%; top: 17.98%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.914859);">starting at the exit to cover the new path. In this way, the VM</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 19.23%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.872885);">records a</span><span role="presentation" dir="ltr" style="left: 14.15%; top: 19.23%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 14.52%; top: 19.23%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.901882);">trace tree</span><span role="presentation" dir="ltr" style="left: 20.1%; top: 19.23%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 20.46%; top: 19.23%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.909883);">covering all the hot paths through the loop.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 10.78%; top: 20.49%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.974313);">Nested loops can be difﬁcult to optimize for tracing VMs. In</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 21.75%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.899072);">a na¨</span><span role="presentation" dir="ltr" style="left: 11.38%; top: 21.75%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.946378);">ıve implementation, inner loops would become hot ﬁrst, and</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 23.01%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.956109);">the VM would start tracing there. When the inner loop exits, the</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 24.27%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.916526);">VM would detect that a different branch was taken. The VM would</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 25.52%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.907258);">try to record a branch trace, and ﬁnd that the trace reaches not the</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 26.78%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.922858);">inner loop header, but the outer loop header. At this point, the VM</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 28.04%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.914088);">could continue tracing until it reaches the inner loop header again,</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 29.3%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.957936);">thus tracing the outer loop inside a trace tree for the inner loop.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 30.56%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.909024);">But this requires tracing a copy of the outer loop for every side exit</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 31.81%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.935562);">and type combination in the inner loop. In essence, this is a form</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 33.07%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.931876);">of unintended tail duplication, which can easily overﬂow the code</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 34.33%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.911344);">cache. Alternatively, the VM could simply stop tracing, and give up</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 35.59%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.902344);">on ever tracing outer loops.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 10.78%; top: 36.84%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.955051);">We solve the nested loop problem by recording</span><span role="presentation" dir="ltr" style="left: 39.98%; top: 36.84%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 40.57%; top: 36.84%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.908376);">nested trace</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 38.1%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.858167);">trees</span><span role="presentation" dir="ltr" style="left: 11.62%; top: 38.1%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.884797);">. Our system traces the inner loop exactly as the na¨</span><span role="presentation" dir="ltr" style="left: 41.13%; top: 38.1%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.90314);">ıve version.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 39.36%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.893753);">The system stops extending the inner tree when it reaches an outer</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 40.62%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.919379);">loop, but then it starts a new trace at the outer loop header. When</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 41.88%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.887121);">the outer loop reaches the inner loop header, the system tries to call</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 43.13%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.887193);">the trace tree for the inner loop. If the call succeeds, the VM records</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 44.39%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.979453);">the call to the inner tree as part of the outer trace and ﬁnishes</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 45.65%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.951132);">the outer trace as normal. In this way, our system can trace any</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 46.91%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.900425);">number of loops nested to any depth without causing excessive tail</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 48.17%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.939314);">duplication.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 10.78%; top: 49.42%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.949937);">These techniques allow a VM to dynamically translate a pro-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 50.68%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.928377);">gram to nested, type-specialized trace trees. Because traces can</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 51.94%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.912424);">cross function call boundaries, our techniques also achieve the ef-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 53.2%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.905589);">fects of inlining. Because traces have no internal control-ﬂow joins,</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 54.46%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.97364);">they can be optimized in linear time by a simple compiler (10).</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 55.71%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.97763);">Thus, our tracing VM efﬁciently performs the same kind of op-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 56.97%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.94299);">timizations that would require interprocedural analysis in a static</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 58.23%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.914823);">optimization setting. This makes tracing an attractive and effective</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 59.49%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.91819);">tool to type specialize even complex function call-rich code.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 10.78%; top: 60.75%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.899918);">We implemented these techniques for an existing JavaScript in-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 62%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.943288);">terpreter, SpiderMonkey. We call the resulting tracing VM</span><span role="presentation" dir="ltr" style="left: 43.63%; top: 62%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 44.09%; top: 62%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.91062);">Trace-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 63.26%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.892872);">Monkey</span><span role="presentation" dir="ltr" style="left: 13.4%; top: 63.26%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.918535);">. TraceMonkey supports all the JavaScript features of Spi-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 64.52%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.908408);">derMonkey, with a 2x-20x speedup for traceable programs.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 10.78%; top: 65.78%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.920729);">This paper makes the following contributions:</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 9.68%; top: 68.17%; font-size: calc(var(--scale-factor)*7.97px); font-family: monospace;">•</span><span role="presentation" dir="ltr" style="left: 10.37%; top: 68.17%; font-size: calc(var(--scale-factor)*7.97px); font-family: monospace;"> </span><span role="presentation" dir="ltr" style="left: 10.94%; top: 68.17%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.921506);">We explain an algorithm for dynamically forming trace trees to</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 10.94%; top: 69.42%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.863012);">cover a program, representing nested loops as nested trace trees.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 9.68%; top: 71.19%; font-size: calc(var(--scale-factor)*7.97px); font-family: monospace;">•</span><span role="presentation" dir="ltr" style="left: 10.37%; top: 71.19%; font-size: calc(var(--scale-factor)*7.97px); font-family: monospace;"> </span><span role="presentation" dir="ltr" style="left: 10.94%; top: 71.19%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.894219);">We explain how to speculatively generate efﬁcient type-specialized</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 10.94%; top: 72.44%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.902734);">code for traces from dynamic language programs.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 9.68%; top: 74.21%; font-size: calc(var(--scale-factor)*7.97px); font-family: monospace;">•</span><span role="presentation" dir="ltr" style="left: 10.37%; top: 74.21%; font-size: calc(var(--scale-factor)*7.97px); font-family: monospace;"> </span><span role="presentation" dir="ltr" style="left: 10.94%; top: 74.2%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.906632);">We validate our tracing techniques in an implementation based</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 10.94%; top: 75.46%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.926429);">on the SpiderMonkey JavaScript interpreter, achieving 2x-20x</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 10.94%; top: 76.72%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.880991);">speedups on many programs.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 10.78%; top: 79.11%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.894043);">The remainder of this paper is organized as follows. Section 3 is</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 80.37%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.915942);">a general overview of trace tree based compilation we use to cap-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 81.63%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.944718);">ture and compile frequently executed code regions. In Section 4</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 82.88%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.9301);">we describe our approach of covering nested loops using a num-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 84.14%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.952326);">ber of individual trace trees. In Section 5 we describe our trace-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 85.4%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.898736);">compilation based speculative type specialization approach we use</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 86.66%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.907273);">to generate efﬁcient machine code from recorded bytecode traces.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 87.92%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.958104);">Our implementation of a dynamic type-specializing compiler for</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 89.17%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.921286);">JavaScript is described in Section 6. Related work is discussed in</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 8.82%; top: 90.43%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.895408);">Section 8. In Section 7 we evaluate our dynamic compiler based on</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 8.97%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace; transform: scaleX(0.872399);">1 for (var i = 2; i &lt; 100; ++i) {</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 10.23%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace;">2</span><span role="presentation" dir="ltr" style="left: 52.57%; top: 10.23%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace;"> </span><span role="presentation" dir="ltr" style="left: 54.88%; top: 10.23%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace; transform: scaleX(0.872399);">if (!primes[i])</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 11.49%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace;">3</span><span role="presentation" dir="ltr" style="left: 52.57%; top: 11.49%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace;"> </span><span role="presentation" dir="ltr" style="left: 56.41%; top: 11.49%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace; transform: scaleX(0.872399);">continue;</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 12.75%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace;">4</span><span role="presentation" dir="ltr" style="left: 52.57%; top: 12.75%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace;"> </span><span role="presentation" dir="ltr" style="left: 54.88%; top: 12.75%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace; transform: scaleX(0.872399);">for (var k = i + i; i &lt; 100; k += i)</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 14%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace;">5</span><span role="presentation" dir="ltr" style="left: 52.57%; top: 14%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace;"> </span><span role="presentation" dir="ltr" style="left: 56.41%; top: 14%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace; transform: scaleX(0.872399);">primes[k] = false;</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 15.26%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace; transform: scaleX(0.872399);">6 }</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 18.04%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.998921);">Figure 1. Sample program: sieve of Eratosthenes.</span><span role="presentation" dir="ltr" style="left: 84.08%; top: 18.04%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 84.68%; top: 18.06%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace; transform: scaleX(0.872399);">primes</span><span role="presentation" dir="ltr" style="left: 89.29%; top: 18.06%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace;"> </span><span role="presentation" dir="ltr" style="left: 89.89%; top: 18.04%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.92401);">is</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 19.3%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.971354);">initialized to an array of 100</span><span role="presentation" dir="ltr" style="left: 69.2%; top: 19.3%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 69.71%; top: 19.32%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace; transform: scaleX(0.872399);">false</span><span role="presentation" dir="ltr" style="left: 73.56%; top: 19.32%; font-size: calc(var(--scale-factor)*8.97px); font-family: monospace;"> </span><span role="presentation" dir="ltr" style="left: 74.08%; top: 19.3%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.941856);">values on entry to this code</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 20.56%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.896622);">snippet.</span><span role="presentation" dir="ltr" style="left: 66.24%; top: 26.75%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.09);">Interpret</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 65.98%; top: 27.51%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00072);">Bytecodes</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 66.41%; top: 32.57%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.10032);">Monitor</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 55.17%; top: 34.64%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.06954);">Record</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 54.79%; top: 35.4%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00072);">LIR</span><span role="presentation" dir="ltr" style="left: 56.1%; top: 35.4%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 56.32%; top: 35.4%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif;">T</span><span role="presentation" dir="ltr" style="left: 56.81%; top: 35.4%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00065);">race</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 77.35%; top: 39.64%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.06223);">Execute</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 76.01%; top: 40.41%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00055);">Compiled</span><span role="presentation" dir="ltr" style="left: 79.58%; top: 40.41%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 79.8%; top: 40.41%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif;">T</span><span role="presentation" dir="ltr" style="left: 80.29%; top: 40.41%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00065);">race</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 77.89%; top: 34.64%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.07027);">Enter</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 76.01%; top: 35.4%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00055);">Compiled</span><span role="presentation" dir="ltr" style="left: 79.58%; top: 35.4%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 79.8%; top: 35.4%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif;">T</span><span role="presentation" dir="ltr" style="left: 80.29%; top: 35.4%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00065);">race</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 54.96%; top: 39.64%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.0764);">Compile</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 54.79%; top: 40.41%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00072);">LIR</span><span role="presentation" dir="ltr" style="left: 56.1%; top: 40.41%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 56.32%; top: 40.41%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif;">T</span><span role="presentation" dir="ltr" style="left: 56.81%; top: 40.41%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00065);">race</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 77.77%; top: 44.65%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.04136);">Leave</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 76.01%; top: 45.41%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00055);">Compiled</span><span role="presentation" dir="ltr" style="left: 79.58%; top: 45.41%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 79.8%; top: 45.41%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif;">T</span><span role="presentation" dir="ltr" style="left: 80.29%; top: 45.41%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00065);">race</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 65.75%; top: 29.25%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00048);">loop</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 65.61%; top: 30.02%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00054);">edge</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 62.72%; top: 34.26%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00072);">hot</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 61.74%; top: 35.02%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00065);">loop/exit</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 54.78%; top: 32.3%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00068);">abort</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 53.98%; top: 33.06%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00059);">recording</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 57.77%; top: 36.71%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif;">ﬁ</span><span role="presentation" dir="ltr" style="left: 58.19%; top: 36.71%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00072);">nish at</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 57%; top: 37.47%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00058);">loop header</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 72.13%; top: 29.91%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00063);">cold/blacklisted</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 73.42%; top: 30.67%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00065);">loop/exit</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 72.6%; top: 32.57%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00067);">compiled trace</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 74.29%; top: 33.33%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00063);">ready</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 69.46%; top: 37.33%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00062);">loop edge with</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 70.02%; top: 38.09%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00076);">same types</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 84.73%; top: 43.29%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00076);">side exit to</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 84.26%; top: 44.05%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00071);">existing trace</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 69.84%; top: 43.02%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00074);">side exit,</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 68.43%; top: 43.78%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00071);">no existing trace</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 82.85%; top: 27.3%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00068);">Overhead</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 82.57%; top: 28.93%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.0007);">Interpreting</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 83.51%; top: 30.51%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.00065);">Native</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 82.5%; top: 25.88%; font-size: calc(var(--scale-factor)*5.17px); font-family: sans-serif; transform: scaleX(1.0737);">Symbol Key</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 49.41%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.982869);">Figure 2.</span><span role="presentation" dir="ltr" style="left: 57.48%; top: 49.41%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 58.21%; top: 49.41%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.927999);">State machine describing the major activities of Trace-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 50.67%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.941073);">Monkey and the conditions that cause transitions to a new activ-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 51.93%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.970355);">ity. In the dark box, TM executes JS as compiled traces. In the</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 53.19%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.903926);">light gray boxes, TM executes JS in the standard interpreter. White</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 54.44%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.924794);">boxes are overhead. Thus, to maximize performance, we need to</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 55.7%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.907393);">maximize time spent in the darkest box and minimize time spent in</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 56.96%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.887107);">the white boxes. The best case is a loop where the types at the loop</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 58.22%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.885496);">edge are the same as the types on entry–then TM can stay in native</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 59.48%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.910927);">code until the loop is done.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 63.07%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.921239);">a set of industry benchmarks. The paper ends with conclusions in</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 64.33%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.898707);">Section 9 and an outlook on future work is presented in Section 10.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 67.08%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif; transform: scaleX(0.900028);">2.</span><span role="presentation" dir="ltr" style="left: 53.14%; top: 67.08%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 54.93%; top: 67.08%; font-size: calc(var(--scale-factor)*10.96px); font-family: sans-serif; transform: scaleX(0.986729);">Overview: Example Tracing Run</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 69.05%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.971667);">This section provides an overview of our system by describing</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 70.31%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.946093);">how TraceMonkey executes an example program. The example</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 71.56%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.903955);">program, shown in Figure 1, computes the ﬁrst 100 prime numbers</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 72.82%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.887121);">with nested loops. The narrative should be read along with Figure 2,</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 74.08%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.926064);">which describes the activities TraceMonkey performs and when it</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 75.34%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.898923);">transitions between the loops.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 53.75%; top: 76.59%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.931809);">TraceMonkey always begins executing a program in the byte-</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 77.85%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.944735);">code interpreter. Every loop back edge is a potential trace point.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 79.11%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.933198);">When the interpreter crosses a loop edge, TraceMonkey invokes</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 80.37%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.879433);">the</span><span role="presentation" dir="ltr" style="left: 53.59%; top: 80.37%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 54.01%; top: 80.37%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.94224);">trace monitor</span><span role="presentation" dir="ltr" style="left: 62.06%; top: 80.37%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.916711);">, which may decide to record or execute a native</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 81.63%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.897143);">trace. At the start of execution, there are no compiled traces yet, so</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 82.88%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.879029);">the trace monitor counts the number of times each loop back edge is</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 84.14%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.885735);">executed until a loop becomes</span><span role="presentation" dir="ltr" style="left: 69.32%; top: 84.14%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif;"> </span><span role="presentation" dir="ltr" style="left: 69.64%; top: 84.14%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.919734);">hot</span><span role="presentation" dir="ltr" style="left: 71.52%; top: 84.14%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.900656);">, currently after 2 crossings. Note</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 85.4%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.880601);">that the way our loops are compiled, the loop edge is crossed before</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 86.66%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.909024);">entering the loop, so the second crossing occurs immediately after</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 87.92%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.928558);">the ﬁrst iteration.</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 53.75%; top: 89.17%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.980441);">Here is the sequence of events broken down by outer loop</span><br role="presentation"><span role="presentation" dir="ltr" style="left: 51.8%; top: 90.43%; font-size: calc(var(--scale-factor)*8.97px); font-family: sans-serif; transform: scaleX(0.94189);">iteration:</span><div class="endOfContent"></div></div><div class="annotationLayer" hidden=""></div><div class="annotationEditorLayer" tabindex="0" hidden="" dir="ltr" data-main-rotation="0" style="pointer-events: none; width: calc(var(--scale-factor) * 612px); height: calc(var(--scale-factor) * 792px);"></div></div><div class="page" data-page-number="3" role="region" aria-label="第 3 页" style="width: calc(var(--scale-factor) * 612px); height: calc(var(--scale-factor) * 792px);"></div><div class="page" data-page-number="4" role="region" aria-label="第 4 页" style="width: calc(var(--scale-factor) * 612px); height: calc(var(--scale-factor) * 792px);"></div><div class="page" data-page-number="5" role="region" aria-label="第 5 页" style="width: calc(var(--scale-factor) * 612px); height: calc(var(--scale-factor) * 792px);"></div><div class="page" data-page-number="6" role="region" aria-label="第 6 页" style="width: calc(var(--scale-factor) * 612px); height: calc(var(--scale-factor) * 792px);"></div><div class="page" data-page-number="7" role="region" aria-label="第 7 页" style="width: calc(var(--scale-factor) * 612px); height: calc(var(--scale-factor) * 792px);"></div><div class="page" data-page-number="8" role="region" aria-label="第 8 页" style="width: calc(var(--scale-factor) * 612px); height: calc(var(--scale-factor) * 792px);"></div><div class="page" data-page-number="9" role="region" aria-label="第 9 页" style="width: calc(var(--scale-factor) * 612px); height: calc(var(--scale-factor) * 792px);"></div><div class="page" data-page-number="10" role="region" aria-label="第 10 页" style="width: calc(var(--scale-factor) * 612px); height: calc(var(--scale-factor) * 792px);"></div><div class="page" data-page-number="11" role="region" aria-label="第 11 页" style="width: calc(var(--scale-factor) * 612px); height: calc(var(--scale-factor) * 792px);"></div><div class="page" data-page-number="12" role="region" aria-label="第 12 页" style="width: calc(var(--scale-factor) * 612px); height: calc(var(--scale-factor) * 792px);"></div><div class="page" data-page-number="13" role="region" aria-label="第 13 页" style="width: calc(var(--scale-factor) * 612px); height: calc(var(--scale-factor) * 792px);"></div><div class="page" data-page-number="14" role="region" aria-label="第 14 页" style="width: calc(var(--scale-factor) * 612px); height: calc(var(--scale-factor) * 792px);"></div></div>
        </div>
      </div> <!-- mainContainer -->

      <div id="dialogContainer">
        <dialog id="passwordDialog">
          <div class="row">
            <label for="password" id="passwordText" data-l10n-id="password_label">输入密码以打开此 PDF 文件。</label>
          </div>
          <div class="row">
            <input type="password" id="password" class="toolbarField">
          </div>
          <div class="buttonRow">
            <button id="passwordCancel" class="dialogButton"><span data-l10n-id="password_cancel">取消</span></button>
            <button id="passwordSubmit" class="dialogButton"><span data-l10n-id="password_ok">确定</span></button>
          </div>
        </dialog>
        <dialog id="documentPropertiesDialog">
          <div class="row">
            <span id="fileNameLabel" data-l10n-id="document_properties_file_name">文件名:</span>
            <p id="fileNameField" aria-labelledby="fileNameLabel">-</p>
          </div>
          <div class="row">
            <span id="fileSizeLabel" data-l10n-id="document_properties_file_size">文件大小:</span>
            <p id="fileSizeField" aria-labelledby="fileSizeLabel">-</p>
          </div>
          <div class="separator"></div>
          <div class="row">
            <span id="titleLabel" data-l10n-id="document_properties_title">标题:</span>
            <p id="titleField" aria-labelledby="titleLabel">-</p>
          </div>
          <div class="row">
            <span id="authorLabel" data-l10n-id="document_properties_author">作者:</span>
            <p id="authorField" aria-labelledby="authorLabel">-</p>
          </div>
          <div class="row">
            <span id="subjectLabel" data-l10n-id="document_properties_subject">主题:</span>
            <p id="subjectField" aria-labelledby="subjectLabel">-</p>
          </div>
          <div class="row">
            <span id="keywordsLabel" data-l10n-id="document_properties_keywords">关键词:</span>
            <p id="keywordsField" aria-labelledby="keywordsLabel">-</p>
          </div>
          <div class="row">
            <span id="creationDateLabel" data-l10n-id="document_properties_creation_date">创建日期:</span>
            <p id="creationDateField" aria-labelledby="creationDateLabel">-</p>
          </div>
          <div class="row">
            <span id="modificationDateLabel" data-l10n-id="document_properties_modification_date">修改日期:</span>
            <p id="modificationDateField" aria-labelledby="modificationDateLabel">-</p>
          </div>
          <div class="row">
            <span id="creatorLabel" data-l10n-id="document_properties_creator">创建者:</span>
            <p id="creatorField" aria-labelledby="creatorLabel">-</p>
          </div>
          <div class="separator"></div>
          <div class="row">
            <span id="producerLabel" data-l10n-id="document_properties_producer">PDF 生成器：</span>
            <p id="producerField" aria-labelledby="producerLabel">-</p>
          </div>
          <div class="row">
            <span id="versionLabel" data-l10n-id="document_properties_version">PDF 版本:</span>
            <p id="versionField" aria-labelledby="versionLabel">-</p>
          </div>
          <div class="row">
            <span id="pageCountLabel" data-l10n-id="document_properties_page_count">页数:</span>
            <p id="pageCountField" aria-labelledby="pageCountLabel">-</p>
          </div>
          <div class="row">
            <span id="pageSizeLabel" data-l10n-id="document_properties_page_size">页面大小：</span>
            <p id="pageSizeField" aria-labelledby="pageSizeLabel">-</p>
          </div>
          <div class="separator"></div>
          <div class="row">
            <span id="linearizedLabel" data-l10n-id="document_properties_linearized">快速 Web 视图：</span>
            <p id="linearizedField" aria-labelledby="linearizedLabel">-</p>
          </div>
          <div class="buttonRow">
            <button id="documentPropertiesClose" class="dialogButton"><span data-l10n-id="document_properties_close">关闭</span></button>
          </div>
        </dialog>
        <dialog id="altTextDialog" aria-labelledby="dialogLabel" aria-describedby="dialogDescription">
          <div id="altTextContainer">
            <div id="overallDescription">
              <span id="dialogLabel" data-l10n-id="editor_alt_text_dialog_label" class="title">Choose an option</span>
              <span id="dialogDescription" data-l10n-id="editor_alt_text_dialog_description">
                Alt text (alternative text) helps when people can’t see the image or when it doesn’t load.
              </span>
            </div>
            <div id="addDescription">
              <div class="radio">
                <div class="radioButton">
                  <input type="radio" id="descriptionButton" name="altTextOption" tabindex="0" aria-describedby="descriptionAreaLabel" checked="">
                  <label for="descriptionButton" data-l10n-id="editor_alt_text_add_description_label">Add a description</label>
                </div>
                <div class="radioLabel">
                  <span id="descriptionAreaLabel" data-l10n-id="editor_alt_text_add_description_description">
                    Aim for 1-2 sentences that describe the subject, setting, or actions.
                  </span>
                </div>
              </div>
              <div class="descriptionArea">
                <textarea id="descriptionTextarea" placeholder="For example, “A young man sits down at a table to eat a meal”" aria-labelledby="descriptionAreaLabel" data-l10n-id="editor_alt_text_textarea" tabindex="0"></textarea>
              </div>
            </div>
            <div id="markAsDecorative">
              <div class="radio">
                <div class="radioButton">
                  <input type="radio" id="decorativeButton" name="altTextOption" aria-describedby="decorativeLabel">
                  <label for="decorativeButton" data-l10n-id="editor_alt_text_mark_decorative_label">Mark as decorative</label>
                </div>
                <div class="radioLabel">
                  <span id="decorativeLabel" data-l10n-id="editor_alt_text_mark_decorative_description">
                    This is used for ornamental images, like borders or watermarks.
                  </span>
                </div>
              </div>
            </div>
            <div id="buttons">
              <button id="altTextCancel" tabindex="0"><span data-l10n-id="editor_alt_text_cancel_button">Cancel</span></button>
              <button id="altTextSave" tabindex="0"><span data-l10n-id="editor_alt_text_save_button">Save</span></button>
            </div>
          </div>
        </dialog>
        <dialog id="printServiceDialog" style="min-width: 200px;">
          <div class="row">
            <span data-l10n-id="print_progress_message">正在准备打印文档…</span>
          </div>
          <div class="row">
            <progress value="0" max="100"></progress>
            <span data-l10n-id="print_progress_percent" data-l10n-args="{ &quot;progress&quot;: 0 }" class="relative-progress">0%</span>
          </div>
          <div class="buttonRow">
            <button id="printCancel" class="dialogButton"><span data-l10n-id="print_progress_close">取消</span></button>
          </div>
        </dialog>
      </div>  <!-- dialogContainer -->

    </div> <!-- outerContainer -->
    <div id="printContainer"></div>

    <input type="file" id="fileInput" class="hidden">
  

<div class="webcopyMask">
    <div class="webcopyAlertBox">
    <h2><svg t="1683188929404" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10729" width="24" height="24"><path d="M834.1 469.2c-19.5-43.8-47.4-82.6-82.9-115.2l-29.1-26.7c-4.3-3.8-11.1-2.1-13 3.3l-13 37.3c-8.1 23.4-23 47.3-44.1 70.8-1.4 1.5-3 1.9-4.1 2-1.1 0.1-2.8-0.1-4.3-1.5-1.4-1.2-2.1-3-2-4.8 3.7-60.2-14.3-128.1-53.7-202C555.3 171 510 123.1 453.4 89.7l-41.3-24.3c-5.4-3.2-12.3 1-12 7.3l2.2 48c1.5 32.8-2.3 61.8-11.3 85.9-11 29.5-26.8 56.9-47 81.5-14.2 17.2-30.1 32.7-47.5 46.1-42.1 32.3-76.8 74.4-100.3 121.5C172.5 503.3 160 556.6 160 610c0 47.2 9.3 92.9 27.7 136 17.8 41.5 43.2 78.9 75.5 110.9 32.4 32 70 57.2 111.9 74.7C418.5 949.8 464.5 959 512 959s93.5-9.2 136.9-27.3c41.9-17.5 79.6-42.6 111.9-74.7 32.4-32 57.8-69.4 75.5-110.9 18.4-43.1 27.7-88.8 27.7-136 0-48.8-10-96.2-29.9-140.9z" fill="#c20808" p-id="10730"></path></svg>
	    <div class="header-btn">
  <a href="2023-AI-score" class="btn">评分细则下载</a> 
	    </div><br><div class="header-btn">
  <a href="2023-AI-doc" class="btn">相关资料下载</a> 
</div><div class="addCenterLogo updated" id="addCenterLogo"></div></body></html>
